package Controllers;

import Configs.Config;
import GUIs.f_nhanvien_nguoithue_hoadon_them;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;
import com.db4o.query.Query;
import com.db4o.query.QueryComparator;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import models.HoaDon;
import models.HopDong;
import models.NhanVien;

public class HoaDonController {

    private final Config conn;
    private BieuThucChinhQuy btcq;

    public HoaDonController(Config conn) {
        this.conn = conn;
    }

    public HoaDon getWithMaHoaDon(String maHoaDon) {
        return this.conn.getConn().query(new Predicate<HoaDon>() {
            @Override
            public boolean match(HoaDon et) {
                return (et.getMahoadon().equals(maHoaDon));
            }
        }).next();
    }

    public String generateMaHoaDon() {
        try {
            Query query = this.conn.getConn().query();
            query.constrain(HoaDon.class);
            Query sortBy = query.sortBy(new QueryComparator<HoaDon>() {
                @Override
                public int compare(HoaDon HoaDonA, HoaDon HoaDonB) {
                    return XuLyChuoi.getNumHoaDon(HoaDonB.getMahoadon()) - XuLyChuoi.getNumHoaDon(HoaDonA.getMahoadon());
                }
            });
            HoaDon hoaDon = (HoaDon) query.execute().next();
            int maxMaHoaDon = XuLyChuoi.getNumHoaDon(hoaDon.getMahoadon()) + 1;
            return XuLyChuoi.joinMaHoaDon(maxMaHoaDon);
        } catch (Exception ex) {
            return "HOADON0001";
        }
    }

    public void Show(JTable tbdsHoaDon, String mshd) {
        DefaultTableModel model = (DefaultTableModel) tbdsHoaDon.getModel();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss dd-MM-yyyy");
        ObjectSet<HoaDon> hoaDons = this.conn.getConn().query(new Predicate<HoaDon>() {
            @Override
            public boolean match(HoaDon et) {
                return et.getHopdong().getMSHD().equals(mshd);
            }
        });
        int stt = 0;
        for (HoaDon hoaDon : hoaDons) {
            Object[] row = {++stt, hoaDon.getMahoadon(), sdf.format(hoaDon.getThoidiemdong()),hoaDon.getTuthang(),hoaDon.getDenthang(),hoaDon.getNam()};
            model.addRow(row);
        }
    }

    public boolean Add(f_nhanvien_nguoithue_hoadon_them them_hoadon) {
        try {
            String ghiChu = them_hoadon.textareaghichu.getText().trim();
            int tuThang = Integer.parseInt(them_hoadon.cbbtuthang.getSelectedItem().toString());
            int denThang = Integer.parseInt(them_hoadon.cbbdenthang.getSelectedItem().toString());

            this.btcq = new BieuThucChinhQuy(ghiChu, "[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
            if (!ghiChu.isEmpty() && !this.btcq.isBoolean()) {
                JOptionPane.showMessageDialog(them_hoadon, "Ghi chú có chứa ký tự đặc biệt.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                them_hoadon.textareaghichu.requestFocus();
            } else if (tuThang > denThang) {
                JOptionPane.showMessageDialog(them_hoadon, "Tháng đóng tiền không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                them_hoadon.cbbtuthang.requestFocus();
            } else {
                NhanVien nhanVienThem = them_hoadon.nhanVienThem;

                HopDong hopDongThemHoaDon = this.conn.getConn().query(new Predicate<HopDong>() {
                    @Override
                    public boolean match(HopDong et) {
                        return et.getMSHD().equals(them_hoadon.maHD);
                    }
                }).next();
                List<HoaDon> dsHoaDonDaDong = hopDongThemHoaDon.getDshoadon();
                Calendar cal = Calendar.getInstance();
                Date currentDate = cal.getTime();
                int year = cal.get(Calendar.YEAR);
                if (!this.kiemTraDaDong(dsHoaDonDaDong, tuThang, denThang, year)) {
                    HoaDon themmoi = new HoaDon(them_hoadon.lbhoadon_tt.getText(), currentDate, ghiChu, (byte) tuThang, (byte) denThang, year);
                    themmoi.setHopdong(hopDongThemHoaDon);
                    hopDongThemHoaDon.adddsHoaDon(themmoi);
                    themmoi.setNhanvien(nhanVienThem);
                    nhanVienThem.addHoaDon(themmoi);
                    this.conn.getConn().store(themmoi);
                    return true;
                } else {
                    JOptionPane.showMessageDialog(them_hoadon, "Bạn đã đóng tiền tháng này!", "Thông báo", JOptionPane.ERROR_MESSAGE);
                }
            }
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(them_hoadon, "Bạn chưa chọn tháng đóng tiền.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            them_hoadon.cbbtuthang.requestFocus();
        }
        return false;
    }

    public void Edit() {

    }

    public boolean Delete(String maHoaDon) throws ParseException {
        ObjectSet<HoaDon> xoa = this.conn.getConn().query(new Predicate<HoaDon>() {
            @Override
            public boolean match(HoaDon et) {
                return et.getMahoadon().equals(maHoaDon);
            }
        });
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss dd-MM-yyyy");
        while (xoa.hasNext()) {
            HoaDon hoaDon = xoa.next();
            Date time = hoaDon.getThoidiemdong();
            Calendar current = Calendar.getInstance();
            String thoiDiemLap = sdf.format(time);
            String currentTime = sdf.format(current.getTime());
            if (DateNTime.checkDelTimeHoaDon(sdf.parse(thoiDiemLap), sdf.parse(currentTime))) {
                hoaDon.getHopdong().removeDsHoaDon(hoaDon);
                hoaDon.getNhanvien().removeHoaDon(hoaDon);
                this.conn.getConn().delete(hoaDon);
            } else {
                JOptionPane.showMessageDialog(null, "Không thể xóa hóa đơn đã lập quá 30 phút!", "Thông báo", JOptionPane.WARNING_MESSAGE);
            }
        }
        return true;
    }

    public boolean kiemTraDaDong(List<HoaDon> dsHoaDon, int tuThang, int denThang, int nam) {
        return dsHoaDon.stream().anyMatch((hoaDon) -> (hoaDon.getNam() == nam && ((hoaDon.getTuthang() <= tuThang && hoaDon.getDenthang() >= tuThang) || (hoaDon.getTuthang() <= denThang && hoaDon.getDenthang() >= denThang))));
    }
}
